package com.ApiBack.springbootinit.service.impl;

import com.ApiBack.springbootinit.common.ErrorCode;
import com.ApiBack.springbootinit.exception.BusinessException;
import com.ApiBack.springbootinit.model.entity.InterfaceInfo;
import com.ApiBack.springbootinit.model.enums.InterfaceStatus;
import com.ApiBack.springbootinit.model.enums.UserRoleEnum;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ApiBack.springbootinit.model.entity.UserInterfaceInfo;
import com.ApiBack.springbootinit.service.UserInterfaceInfoService;
import com.ApiBack.springbootinit.mapper.UserInterfaceInfoMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author Lenovo
 * @description 针对表【user_interface_info(用户调用接口关系)】的数据库操作Service实现
 * @createDate 2024-03-01 13:01:16
 */
@Service
public class UserInterfaceInfoServiceImpl extends ServiceImpl<UserInterfaceInfoMapper, UserInterfaceInfo>
        implements UserInterfaceInfoService {

    ReentrantLock lock1 = new ReentrantLock();
    ReentrantLock lock2 = new ReentrantLock();

    @Override
    public void validInterfaceInfo(UserInterfaceInfo userInterfaceInfo, boolean b) {
        if (userInterfaceInfo == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        // 创建时，所有参数必须非空
        if (b) {
            Long userId = userInterfaceInfo.getUserId();
            Long interfaceInfoId = userInterfaceInfo.getInterfaceInfoId();
            if (userId == null || userId <= 0 || interfaceInfoId == null || interfaceInfoId <= 0) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR);
            }
        }

        //修改时，一些必要参数必须非空
        if (!b) {
            Long id = userInterfaceInfo.getId();
            if (id == null || id <= 0) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR);
            }
        }

    }

    @Override
    @Transactional
    public boolean invokeCount(long interfaceInfoId, long userId) {
        // 判断
        if (interfaceInfoId <= 0 || userId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        boolean result=false;


        QueryWrapper<UserInterfaceInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("interfaceInfoId", interfaceInfoId);
        queryWrapper.eq("userId", userId);
        // todo 存在线程安全问题,但直接加锁可能影响性能,这里尝试一下Redis(单线程)，做一个前后数据优化对比
        UserInterfaceInfo userInterfaceInfo = this.baseMapper.selectOne(queryWrapper);


        if (userInterfaceInfo==null)
        {
            lock1.lock();
            try {
                UserInterfaceInfo userInterfaceInfo1 = new UserInterfaceInfo();
                userInterfaceInfo1.setUserId(userId);
                userInterfaceInfo1.setInterfaceInfoId(interfaceInfoId);
                userInterfaceInfo1.setLeftNum(9);
                userInterfaceInfo1.setTotalNum(1);
                result = this.save(userInterfaceInfo1);
            } catch (Exception e) {
                log.error("数据库操作失败",e);
            } finally {
                lock1.unlock();
            }
        }

        else {
           lock2.lock();

            try {
                Integer leftNum = userInterfaceInfo.getLeftNum();
                Integer totalNum = userInterfaceInfo.getTotalNum();
                if (leftNum<=0)
                {
                    return result;
                }
                userInterfaceInfo.setLeftNum(leftNum-1);
                userInterfaceInfo.setTotalNum(totalNum+1);
                result = this.updateById(userInterfaceInfo);
            } catch (Exception e) {
                log.error("数据库操作失败");
            } finally {
                lock2.unlock();
            }

        }

        return result;

    }



}




